package br.com.conhecimento.ejb.service;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import br.com.conhecimento.core.data.GestaoDemandaClienteDao;
import br.com.conhecimento.core.data.GestaoDemandaDao;
import br.com.conhecimento.core.data.GestaoDemandaFlagDao;
import br.com.conhecimento.core.data.GestaoDemandaHistoricoDao;
import br.com.conhecimento.core.data.GestaoDemandaPendenciaDao;
import br.com.conhecimento.core.data.GestaoDemandaPrioridadeDao;
import br.com.conhecimento.core.data.GestaoDemandaReceitaDao;
import br.com.conhecimento.core.data.GestaoDemandaStatusDao;
import br.com.conhecimento.core.data.GestaoDemandaTipoDao;
import br.com.conhecimento.core.data.GestaoUsuarioDao;
import br.com.conhecimento.core.model.GestaoDemanda;
import br.com.conhecimento.core.model.GestaoDemandaHistorico;
import br.com.conhecimento.core.util.DateUtil;
import br.com.conhecimento.ejb.client.vo.funcionalidade.CadastroDemandaHistoricoVO;
import br.com.conhecimento.ejb.client.vo.funcionalidade.CadastroDemandaVO;
import br.com.conhecimento.ejb.client.vo.funcionalidade.ConsultaDemandaHistoricoVO;
import br.com.conhecimento.ejb.client.vo.funcionalidade.ConsultaDemandaVO;
import br.com.conhecimento.ejb.client.vo.modelo.DemandaVO;
import br.com.conhecimento.ejb.client.vo.modelo.HistoricoVO;
import br.com.conhecimento.ejb.server.util.Utils;

@Service
@Transactional
public class DemandaService {

	@Autowired
	private GestaoDemandaStatusDao gestaoDemandaStatusDao;

	@Autowired
	private GestaoDemandaDao gestaoDemandaDao;
	
	@Autowired
	private GestaoDemandaHistoricoDao gestaoDemandaHistoricoDao;

	@Autowired
	private GestaoDemandaFlagDao gestaoDemandaFlagDao;

	@Autowired
	private GestaoDemandaPendenciaDao gestaoDemandaPendenciaDao;

	@Autowired
	private GestaoDemandaPrioridadeDao gestaoDemandaPrioridadeDao;

	@Autowired
	private GestaoDemandaReceitaDao gestaoDemandaReceitaDao;

	@Autowired
	private GestaoDemandaClienteDao gestaoDemandaClienteDao;

	@Autowired
	private GestaoDemandaTipoDao gestaoDemandaTipoDao;

	@Autowired
	private GestaoUsuarioDao gestaoUsuarioDao;

	@Autowired
	private JavaMailSender mailSender;

	@Autowired
	private SimpleMailMessage alertMailMessage;

	public CadastroDemandaVO cadastrarDemanda(
			CadastroDemandaVO cadastroDemandaVO) {

		try {

			cadastroDemandaVO = realizaValidacoesDemanda(cadastroDemandaVO);

			if (cadastroDemandaVO.getStatus() != null) {
				return cadastroDemandaVO;
			}

			try {
				GestaoDemanda demanda = new GestaoDemanda();

				demanda.setId(cadastroDemandaVO.getDemanda().getId());

				demanda.setAcaoEsperada(cadastroDemandaVO.getDemanda().getAcaoEsperada());
				demanda.setAtividade(cadastroDemandaVO.getDemanda().getAtividade());
				demanda.setAtivo(cadastroDemandaVO.getDemanda().getAtivo());
				demanda.setCliente(cadastroDemandaVO.getDemanda().getIdCliente() != null
						&& cadastroDemandaVO.getDemanda().getIdCliente() != 0 ? gestaoDemandaClienteDao
						.getCliente(cadastroDemandaVO.getDemanda().getIdCliente()) : null);
				demanda.setDataConclusaoEfetiva(new Timestamp(DateUtil.getDate(
						cadastroDemandaVO.getDemanda().getDataConclusaoEfetiva()).getTime()));
				demanda.setDataConclusaoPlanejada(new Timestamp(DateUtil
						.getDate(cadastroDemandaVO.getDemanda().getDataConclusaoPlanejada())
						.getTime()));
				demanda.setDataSolicitacao(new Timestamp(DateUtil.getDate(
						cadastroDemandaVO.getDemanda().getDataSolicitacao()).getTime()));
				demanda.setEsforco(cadastroDemandaVO.getDemanda().getEsforco());
				demanda.setFlag(cadastroDemandaVO.getDemanda().getIdFlag() != null
						&& cadastroDemandaVO.getDemanda().getIdFlag() != 0 ? gestaoDemandaFlagDao
						.getFlag(cadastroDemandaVO.getDemanda().getIdFlag()) : null);
				demanda.setNomeCliente(cadastroDemandaVO.getDemanda().getNomeCliente());
				demanda.setOutraArea(cadastroDemandaVO.getDemanda().getOutraArea());
				demanda.setPlanejada(cadastroDemandaVO.getDemanda().getPlanejada());
				demanda.setPrioridade(cadastroDemandaVO.getDemanda().getIdPrioridade() != null
						&& cadastroDemandaVO.getDemanda().getIdPrioridade() != 0 ? gestaoDemandaPrioridadeDao
						.getPrioridade(cadastroDemandaVO.getDemanda().getIdPrioridade())
						: null);
				demanda.setPublico(cadastroDemandaVO.getDemanda().getPublico());
				demanda.setReceita(cadastroDemandaVO.getDemanda().getIdReceita() != null
						&& cadastroDemandaVO.getDemanda().getIdReceita() != 0 ? gestaoDemandaReceitaDao
						.getReceita(cadastroDemandaVO.getDemanda().getIdReceita()) : null);
				demanda.setResponsavel(cadastroDemandaVO.getDemanda().getResponsavel());
				demanda.setSolicitante(cadastroDemandaVO.getDemanda().getIdSolicitante() != null
						&& cadastroDemandaVO.getDemanda().getIdSolicitante() != 0 ? gestaoUsuarioDao
						.getUsuario(cadastroDemandaVO.getDemanda().getIdSolicitante())
						: null);
				demanda.setStatus(cadastroDemandaVO.getDemanda().getIdStatus() != null
						&& cadastroDemandaVO.getDemanda().getIdStatus() != 0 ? gestaoDemandaStatusDao
						.getStatus(cadastroDemandaVO.getDemanda().getIdStatus()) : null);
				demanda.setTipo(cadastroDemandaVO.getDemanda().getIdTipo() != null
						&& cadastroDemandaVO.getDemanda().getIdTipo() != 0 ? gestaoDemandaTipoDao
						.getTipo(cadastroDemandaVO.getDemanda().getIdTipo()) : null);
				demanda.setUsuario(cadastroDemandaVO.getDemanda().getIdUsuario() != null
						&& cadastroDemandaVO.getDemanda().getIdUsuario() != 0 ? gestaoUsuarioDao
						.getUsuario(cadastroDemandaVO.getDemanda().getIdUsuario()) : null);

				gestaoDemandaDao.makePersistent(demanda);
			} catch (Exception e) {
				cadastroDemandaVO
						.setStatus(CadastroDemandaVO.StatusCadastroDemandaEnum.ERRO);
				return cadastroDemandaVO;
			}

		} catch (Exception e) {
			Utils.sendMailException(alertMailMessage, mailSender,
					"ERRO AO CADASTRAR DEMANDA", e);
		}

		cadastroDemandaVO
				.setStatus(CadastroDemandaVO.StatusCadastroDemandaEnum.SUCESSO);
		return cadastroDemandaVO;

	}

	public CadastroDemandaHistoricoVO cadastrarDemandaHistorico(
			CadastroDemandaHistoricoVO cadastroDemandaHistoricoVO) {

		try {

			cadastroDemandaHistoricoVO = realizaValidacoesDemandaHistorico(cadastroDemandaHistoricoVO);

			if (cadastroDemandaHistoricoVO.getStatus() != null) {
				return cadastroDemandaHistoricoVO;
			}

			try {
				GestaoDemandaHistorico demanda = new GestaoDemandaHistorico();

				demanda.setDataModificacao(new Timestamp(new Date().getTime()));
				demanda.setDescricao(cadastroDemandaHistoricoVO.getDescricao());
				demanda.setDemanda(gestaoDemandaDao
						.getDemanda(cadastroDemandaHistoricoVO.getDemanda()
								.getId()));

				demanda.setAcaoEsperada(cadastroDemandaHistoricoVO.getDemanda()
						.getAcaoEsperada());
				demanda.setAtividade(cadastroDemandaHistoricoVO.getDemanda()
						.getAtividade());
				demanda.setAtivo(cadastroDemandaHistoricoVO.getDemanda()
						.getAtivo());
				demanda.setCliente(cadastroDemandaHistoricoVO.getDemanda()
						.getIdCliente() != null
						&& cadastroDemandaHistoricoVO.getDemanda()
								.getIdCliente() != 0 ? gestaoDemandaClienteDao
						.getCliente(cadastroDemandaHistoricoVO.getDemanda()
								.getIdCliente()) : null);
				demanda.setDataConclusaoEfetiva(new Timestamp(DateUtil.getDate(
						cadastroDemandaHistoricoVO.getDemanda()
								.getDataConclusaoEfetiva()).getTime()));
				demanda.setDataConclusaoPlanejada(new Timestamp(DateUtil
						.getDate(
								cadastroDemandaHistoricoVO.getDemanda()
										.getDataConclusaoPlanejada()).getTime()));
				demanda.setDataSolicitacao(new Timestamp(DateUtil.getDate(
						cadastroDemandaHistoricoVO.getDemanda()
								.getDataSolicitacao()).getTime()));
				demanda.setEsforco(cadastroDemandaHistoricoVO.getDemanda()
						.getEsforco());
				demanda.setFlag(cadastroDemandaHistoricoVO.getDemanda()
						.getIdFlag() != null
						&& cadastroDemandaHistoricoVO.getDemanda().getIdFlag() != 0 ? gestaoDemandaFlagDao
						.getFlag(cadastroDemandaHistoricoVO.getDemanda()
								.getIdFlag()) : null);
				demanda.setNomeCliente(cadastroDemandaHistoricoVO.getDemanda()
						.getNomeCliente());
				demanda.setOutraArea(cadastroDemandaHistoricoVO.getDemanda()
						.getOutraArea());
				demanda.setPlanejada(cadastroDemandaHistoricoVO.getDemanda()
						.getPlanejada());
				demanda.setPrioridade(cadastroDemandaHistoricoVO.getDemanda()
						.getIdPrioridade() != null
						&& cadastroDemandaHistoricoVO.getDemanda()
								.getIdPrioridade() != 0 ? gestaoDemandaPrioridadeDao
						.getPrioridade(cadastroDemandaHistoricoVO.getDemanda()
								.getIdPrioridade()) : null);
				demanda.setPublico(cadastroDemandaHistoricoVO.getDemanda()
						.getPublico());
				demanda.setReceita(cadastroDemandaHistoricoVO.getDemanda()
						.getIdReceita() != null
						&& cadastroDemandaHistoricoVO.getDemanda()
								.getIdReceita() != 0 ? gestaoDemandaReceitaDao
						.getReceita(cadastroDemandaHistoricoVO.getDemanda()
								.getIdReceita()) : null);
				demanda.setResponsavel(cadastroDemandaHistoricoVO.getDemanda()
						.getResponsavel());
				demanda.setSolicitante(cadastroDemandaHistoricoVO.getDemanda()
						.getIdSolicitante() != null
						&& cadastroDemandaHistoricoVO.getDemanda()
								.getIdSolicitante() != 0 ? gestaoUsuarioDao
						.getUsuario(cadastroDemandaHistoricoVO.getDemanda()
								.getIdSolicitante()) : null);
				demanda.setStatus(cadastroDemandaHistoricoVO.getDemanda()
						.getIdStatus() != null
						&& cadastroDemandaHistoricoVO.getDemanda()
								.getIdStatus() != 0 ? gestaoDemandaStatusDao
						.getStatus(cadastroDemandaHistoricoVO.getDemanda()
								.getIdStatus()) : null);
				demanda.setTipo(cadastroDemandaHistoricoVO.getDemanda()
						.getIdTipo() != null
						&& cadastroDemandaHistoricoVO.getDemanda().getIdTipo() != 0 ? gestaoDemandaTipoDao
						.getTipo(cadastroDemandaHistoricoVO.getDemanda()
								.getIdTipo()) : null);
				demanda.setUsuario(cadastroDemandaHistoricoVO.getDemanda()
						.getIdUsuario() != null
						&& cadastroDemandaHistoricoVO.getDemanda()
								.getIdUsuario() != 0 ? gestaoUsuarioDao
						.getUsuario(cadastroDemandaHistoricoVO.getDemanda()
								.getIdUsuario()) : null);

				gestaoDemandaHistoricoDao.makePersistent(demanda);
			} catch (Exception e) {
				cadastroDemandaHistoricoVO.setStatus(
						CadastroDemandaHistoricoVO.StatusCadastroDemandaHistoricoEnum.ERRO);
				return cadastroDemandaHistoricoVO;
			}

		} catch (Exception e) {
			Utils.sendMailException(alertMailMessage, mailSender,
					"ERRO AO CADASTRAR HISTÓRICO DE DEMANDA", e);
		}

		cadastroDemandaHistoricoVO.setStatus(
				CadastroDemandaHistoricoVO.StatusCadastroDemandaHistoricoEnum.SUCESSO);
		return cadastroDemandaHistoricoVO;

	}

	public ConsultaDemandaVO consultarDemandas(
			ConsultaDemandaVO consultaDemandaVO) {

		try {

			consultaDemandaVO = realizaValidacoesConsulta(consultaDemandaVO);

			if (consultaDemandaVO.getStatus() != null) {
				return consultaDemandaVO;
			}

			List<GestaoDemanda> demandas = gestaoDemandaDao.consultarDemandas(
					consultaDemandaVO.getDtConclusaoFin(),
					consultaDemandaVO.getDtConclusaoIni(),
					consultaDemandaVO.getDtSolicitacaoFin(),
					consultaDemandaVO.getDtSolicitacaoIni(),
					consultaDemandaVO.getIdPrioridade(),
					consultaDemandaVO.getIdSolicitante(),
					consultaDemandaVO.getIdStatus(),
					consultaDemandaVO.getIdTipo(),
					consultaDemandaVO.getIdUsuario());

			if (demandas == null) {
				consultaDemandaVO
						.setStatus(ConsultaDemandaVO.StatusConsultaDemandaVOEnum.ERRO);
				return consultaDemandaVO;
			}

			if (demandas.isEmpty()) {
				consultaDemandaVO
						.setStatus(ConsultaDemandaVO.StatusConsultaDemandaVOEnum.NAO_POSSUI_REGISTROS);
				return consultaDemandaVO;
			}

			for (GestaoDemanda d : demandas) {
				consultaDemandaVO.getRetorno().add(converterDemandaParaVO(d));
			}

		} catch (Exception E) {
			consultaDemandaVO
			.setStatus(ConsultaDemandaVO.StatusConsultaDemandaVOEnum.ERRO);
			return consultaDemandaVO;
		}

		consultaDemandaVO
				.setStatus(ConsultaDemandaVO.StatusConsultaDemandaVOEnum.SUCESSO);
		return consultaDemandaVO;

	}

	
	public ConsultaDemandaHistoricoVO consultarHisotirco(
			ConsultaDemandaHistoricoVO consultaDemandaHistoricoVO) {

		try {
			
			if(consultaDemandaHistoricoVO.getId() == null) {
				consultaDemandaHistoricoVO
				.setStatus(ConsultaDemandaHistoricoVO.StatusConsultaDemandaHistoricoEnum.ERRO);
				return consultaDemandaHistoricoVO;
			}
			
			GestaoDemandaHistorico historico = gestaoDemandaHistoricoDao.getHistorico(consultaDemandaHistoricoVO.getId());
			
			if(historico == null) {
				consultaDemandaHistoricoVO
				.setStatus(ConsultaDemandaHistoricoVO.StatusConsultaDemandaHistoricoEnum.NAO_ENCONTRADO);
				return consultaDemandaHistoricoVO;
			}
			
			HistoricoVO historicoVo = new HistoricoVO();
			
			historicoVo.setDescricao(historico.getDescricao());
			historicoVo.setDataModificacao(historico.getDataModificacao() != null ? DateUtil.formataDataHoraSegundo(historico.getDataModificacao()) : null);
			historicoVo.setId(historico.getId());
			historicoVo.setDemanda(converterDemandaParaVO(historico.getDemanda()));
			
			consultaDemandaHistoricoVO.setDemanda(historicoVo);

		} catch (Exception E) {
			consultaDemandaHistoricoVO
			.setStatus(ConsultaDemandaHistoricoVO.StatusConsultaDemandaHistoricoEnum.ERRO);
			return consultaDemandaHistoricoVO;
		}

		consultaDemandaHistoricoVO
				.setStatus(ConsultaDemandaHistoricoVO.StatusConsultaDemandaHistoricoEnum.SUCESSO);
		return consultaDemandaHistoricoVO;

	}
	
	
	private CadastroDemandaVO converterDemandaParaVO(GestaoDemanda d) {
		CadastroDemandaVO demandaVo = new CadastroDemandaVO();
		
		demandaVo.setDemanda(new DemandaVO());
		
		demandaVo.getDemanda().setAcaoEsperada(d.getAcaoEsperada());
		demandaVo.getDemanda().setAtividade(d.getAtividade());
		demandaVo.getDemanda().setAtivo(d.getAtivo());
		demandaVo.getDemanda().setDataConclusaoEfetiva(DateUtil.formataData(d.getDataConclusaoEfetiva(), "dd/MM/yyyy"));
		demandaVo.getDemanda().setDataConclusaoPlanejada(DateUtil.formataData(d.getDataConclusaoPlanejada(), "dd/MM/yyyy"));
		demandaVo.getDemanda().setDataSolicitacao(DateUtil.formataData(d.getDataSolicitacao(), "dd/MM/yyyy"));
		demandaVo.getDemanda().setEsforco(d.getEsforco());
		demandaVo.getDemanda().setId(d.getId());
		demandaVo.getDemanda().setIdCliente(d.getCliente() != null ? d.getCliente().getId() : 0);
		demandaVo.getDemanda().setIdFlag(d.getFlag() != null ? d.getFlag().getId() : 0);
		demandaVo.getDemanda().setIdPendencia(null);
		demandaVo.getDemanda().setIdPrioridade(d.getPrioridade() != null ? d.getPrioridade().getId() : 0);
		demandaVo.getDemanda().setIdReceita(d.getReceita()!= null ? d.getReceita().getId() : 0);
		demandaVo.getDemanda().setIdSolicitante(d.getSolicitante()!= null ? d.getSolicitante().getId() : 0);
		demandaVo.getDemanda().setIdStatus(d.getStatus() != null ? d.getStatus().getId() : 0);
		demandaVo.getDemanda().setIdTipo(d.getTipo() != null ? d.getTipo().getId() : 0);
		demandaVo.getDemanda().setIdUsuario(d.getUsuario() != null ? d.getUsuario().getId() : null);
		demandaVo.getDemanda().setNomeCliente(d.getNomeCliente());
		demandaVo.getDemanda().setOutraArea(d.getOutraArea());
		demandaVo.getDemanda().setPlanejada(d.getPlanejada());
		demandaVo.getDemanda().setPublico(d.getPublico());
		demandaVo.getDemanda().setResponsavel(d.getResponsavel());
		
		return demandaVo;
	}

	private ConsultaDemandaVO realizaValidacoesConsulta(
			ConsultaDemandaVO consultaDemandaVO) {
		
		if((consultaDemandaVO.getDtConclusaoIni() != null && !consultaDemandaVO.getDtConclusaoIni().equals("")) && (consultaDemandaVO.getDtConclusaoFin() != null && !consultaDemandaVO.getDtConclusaoFin().equals(""))) {
			if(!DateUtil.isValidDate(consultaDemandaVO.getDtConclusaoFin()) || !DateUtil.isValidDate(consultaDemandaVO.getDtConclusaoIni())) {
				consultaDemandaVO.setStatus(ConsultaDemandaVO.StatusConsultaDemandaVOEnum.DATA_CONCLUSAO_INVALIDA);
				return consultaDemandaVO;
			}
		}
		
		if((consultaDemandaVO.getDtSolicitacaoIni() != null && !consultaDemandaVO.getDtSolicitacaoIni().equals("")) && (consultaDemandaVO.getDtSolicitacaoFin() != null && !consultaDemandaVO.getDtSolicitacaoFin().equals(""))) {
			if(!DateUtil.isValidDate(consultaDemandaVO.getDtSolicitacaoFin()) || !DateUtil.isValidDate(consultaDemandaVO.getDtSolicitacaoIni())) {
				consultaDemandaVO.setStatus(ConsultaDemandaVO.StatusConsultaDemandaVOEnum.DATA_SOLICITACAO_INVALIDA);
				return consultaDemandaVO;
			}
		}
		
		return consultaDemandaVO;
	}

	private CadastroDemandaHistoricoVO realizaValidacoesDemandaHistorico(
			CadastroDemandaHistoricoVO cadastroDemandaHistoricoVO) {

		if (cadastroDemandaHistoricoVO.getDemanda() == null) {
			cadastroDemandaHistoricoVO
					.setStatus(CadastroDemandaHistoricoVO.StatusCadastroDemandaHistoricoEnum.ERRO);
			return cadastroDemandaHistoricoVO;
		}

		if (cadastroDemandaHistoricoVO.getDemanda().getId() == null
				|| cadastroDemandaHistoricoVO.getDemanda().getId() == 0) {
			cadastroDemandaHistoricoVO
					.setStatus(CadastroDemandaHistoricoVO.StatusCadastroDemandaHistoricoEnum.ERRO);
			return cadastroDemandaHistoricoVO;
		}

		return null;
	}

	private CadastroDemandaVO realizaValidacoesDemanda(
			CadastroDemandaVO cadastroDemandaVO) {

		if (cadastroDemandaVO.getDemanda().getIdTipo() == null
				|| cadastroDemandaVO.getDemanda().getIdTipo() == 0) {
			cadastroDemandaVO
					.setStatus(CadastroDemandaVO.StatusCadastroDemandaEnum.TIPO_DEMANDA_OBG);
			return cadastroDemandaVO;
		}

		if (cadastroDemandaVO.getDemanda().getIdPrioridade() == null
				|| cadastroDemandaVO.getDemanda().getIdPrioridade() == 0) {
			cadastroDemandaVO
					.setStatus(CadastroDemandaVO.StatusCadastroDemandaEnum.PRIORIDADE_DEMANDA_OBG);
			return cadastroDemandaVO;
		}

		if (cadastroDemandaVO.getDemanda().getIdUsuario() == null) {
			cadastroDemandaVO
					.setStatus(CadastroDemandaVO.StatusCadastroDemandaEnum.ERRO);
			return cadastroDemandaVO;
		}

		return cadastroDemandaVO;

	}

}
